package example;

import java.net.*;
import java.rmi.RemoteException;
import java.io.*;
import java.sql.*;

public class DistributedServer {
	public String tableName = "";
	public static int BUFFER_SIDE = 20;
	public static int queryId = 0;
	public String lockTable = "";
	public boolean isMaster = false;
	
	//public ForwardRequestThread fwdRequest;
	public WorkerThread wkprocess;
	public SplitJoinThread spprocess;
	
	public void init() {
		//fwdRequest = new Thread();
	}

	public Connection conn = null;
	public void sqlConn() throws RemoteException , Exception
	{
//		String user ="kpham";
//		String passwd ="ao62dvvd";
//		String jdbcURL = "jdbc:oracle:thin:@oracle.cs.purdue.edu:1521:orb";
//		String driverName = "oracle.jdbc.driver.OracleDriver";

//		String user ="root";
//		String passwd ="1";
//		String jdbcURL = "jdbc:mysql://127.0.0.1:3306/ps";
//		String driverName = "com.mysql.jdbc.Driver";
		
		String user ="root";
		String passwd ="1";
		String jdbcURL = "jdbc:postgresql://127.0.0.1:5432/postgis";
		String driverName = "org.postgresql.Driver";
		
		Class.forName(driverName).newInstance();
		conn = DriverManager.getConnection(jdbcURL,user,passwd);
	}
	public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = null;        
        boolean listening = true;
        DistributedServer ks = new DistributedServer();
        ks.setInput();
        ks.registerServer();
        try {
            serverSocket = new ServerSocket(8888);
        } catch (IOException e) {
            System.err.println("Could not listen on port: 8888.");
            System.exit(-1);
        }
        //server listening client query
        while (listening) {
        	Socket acptSocket = serverSocket.accept();
        	SimpleProtocol kpp = new SimpleProtocol();
        	kpp.senderIP = acptSocket.getInetAddress().toString();//client IP
        	kpp.senderIP = kpp.senderIP.substring(1,kpp.senderIP.length());
        	
        	//data server simply create data thread
        	//which executed query, return result to Master
        	//or get chunk of data to join from others
        	if(!ks.isMaster) {
        		ks.wkprocess  = new WorkerThread(acptSocket, kpp, queryId);
        		ks.wkprocess.start();
        		queryId++;
        	}
        	//master server
        	//get query, create corresponding thread
            //this thread will: 
            //create threads to connect others data servers
            //join the result returning by other threads 
        	else {
        		ks.spprocess  = new SplitJoinThread(acptSocket, kpp, queryId);
        		ks.spprocess.start();
        		queryId++;
        	}
        }

        serverSocket.close();
    }
    public void registerServer() throws RemoteException, Exception {
    	InetAddress myself = InetAddress.getLocalHost ();
    	DBConnection dbConn = new DBConnection();
    	String registerSQL = "insert into distributedHost values ('"+this.tableName+ "', '"+myself.getHostName()+"')";
    	dbConn.executeCmd(registerSQL);
    	registerSQL = "commit";
    	dbConn.executeCmd(registerSQL);
    }
    public void setInput() {
    	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String tblName = null;
        try {
        	tblName = br.readLine();
        } catch (IOException ioe) {
           System.out.println("IO error trying to read your name!");
           System.exit(1);
        }
        this.tableName = tblName;
    }
    public static void  getLocalnetdetails (){
        try {
        InetAddress myself = InetAddress.getLocalHost ();
        }
        catch (UnknownHostException ex){
        	System.out.println ("Failed to find myself:");
        ex.printStackTrace ();
        }
    }
}
